-
Notifications
You must be signed in to change notification settings - Fork 0
/
zad1.py
71 lines (52 loc) · 2.17 KB
/
zad1.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
"""
ZŁOŻONOŚĆ
Obliczeniowa: O(N)
Pamięciowa: O(1)
UWAGA! Nie wiem, czy dobrze.
f(i) - funkcja, która wskazuje, jaki prostokąt należy usunąć spośród wszystkich
prostokątów o indeksach 0, 1, 2, ..., i, aby otrzymane pole powierzchni przecięcia
było jak największe. Rozwiązaniem jest f(n), gdzie n to liczba wszystkich prostokątów.
Kolejne wartości funkcji obliczamy w taki sposób, że sprawdzamy, za każdym razem, czy
bardziej opłaca nam się usunąć nowy prostokąt (o indeksie i), zostawiając wszytkie
poprzednie prostokąty (na przecięcie będą się wtedy składać prostokąty o indeksach 0, 1,
2, ..., i - 1), czy lepiej jest zotawić ten nowy prostokąt i usunąć poprzednio wybrany
do usunięcia prostokąt.
"""
from zad1testy import runtests
def cut(rect1, rect2):
x11, y11, x12, y12 = rect1
x21, y21, x22, y22 = rect2
x1 = max(x11, x21)
y1 = max(y11, y21)
x2 = min(x12, x22)
y2 = min(y12, y22)
return x1, y1, x2, y2
def rect_area(x1, y1, x2, y2):
return (x2 - x1) * (y2 - y1)
def rect(D):
n = len(D)
# If there is nothing to remove
if n < 3: return None
# Choose which rectangle from the first 3 ones
# might be removed if we had only 3 rectangles
cuts = [rect_area(*cut(D[i], D[j])) for i, j in ((1, 2), (0, 2), (0, 1))]
to_remove = cuts.index(max(cuts))
remaining = [0, 1, 2]
remaining.remove(to_remove)
cut_coords = cut(D[remaining[0]], D[remaining[1]])
for i in range(3, n):
# If we remove the i-th rectangle
curr_remove_cut_coords = cut(cut_coords, D[to_remove])
curr_remove_area = rect_area(*curr_remove_cut_coords)
# If we remove the previously chosen rectangle
prev_remove_cut_coords = cut(cut_coords, D[i])
prev_remove_area = rect_area(*prev_remove_cut_coords)
# print('prev', to_remove, 'curr', i, 'prev area', prev_remove_area, 'curr area', curr_remove_area)
# Choose better of both solutions above
if curr_remove_area > prev_remove_area:
cut_coords = curr_remove_cut_coords
to_remove = i
else:
cut_coords = prev_remove_cut_coords
return to_remove
runtests(rect)